import { resolve, basename } from 'path';
import * as fs from 'fs';
import { log } from '../../utils';

/**
 * 创建目录链接
 *
 * @author chitanda
 * @date 2021-04-18 19:04:38
 * @export
 * @param {string} sourceStr
 * @param {string} targetStr
 * @param {boolean} [force=false]
 * @return {*}  {void}
 */
export function linkDir(sourceStr: string, targetStr: string, force = false): void {
  try {
    const sourcePath: string = resolve(process.cwd(), sourceStr);
    let targetPath: string = resolve(process.cwd(), targetStr);
    // 源文件是否存在
    if (fs.existsSync(sourcePath)) {
      // 目标是否已存在
      if (fs.existsSync(targetPath)) {
        let t = fs.lstatSync(targetPath);
        // 未指定链接名称，拼接原有文件名称
        if (t.isDirectory()) {
          const fileName = basename(sourcePath);
          targetPath = resolve(targetPath, fileName);
        }
        if (fs.existsSync(targetPath)) {
          t = fs.lstatSync(targetPath);
          if (force === true) {
            if (t.isFile()) {
              fs.rmSync(targetPath);
            } else if (t.isDirectory()) {
              fs.rmdirSync(targetPath);
            } else if (t.isSymbolicLink()) {
              fs.unlinkSync(targetPath);
            }
          } else {
            // 存在的目标是否为软链接
            if (t.isSymbolicLink()) {
              const linkPath = fs.readlinkSync(targetPath);
              // 如果为软链接，是否为同一个「文件 or 目录」
              if (linkPath === sourcePath) {
                log.warn('', `软链接已存在，无需重复建立!`);
              } else {
                log.error('', `目标[${targetStr}]已建立软链接指向[${linkPath}]，无法再次建立!`);
              }
              return;
            } else if (t.isFile()) {
              log.error('', `目标[${targetStr}]已存在，无法建立软链接!`);
              return;
            }
          }
        }
      }
      // 建立软链接
      fs.symlinkSync(sourcePath, targetPath);
      log.info('', `软链接建立成功：${sourcePath} ==> ${targetPath}`);
    } else {
      log.error('', `目录不存在：${sourceStr}`);
    }
  } catch (err) {
    const msg: string = err.message;
    if (msg.indexOf('EPERM: operation not permitted, symlink') === 0) {
      log.error('', `当前用户无权建立软链接，请尝试以管理员运行!`);
    } else {
      log.error('', msg);
    }
  }
}
